package com.smart.campus.quartz.task;

import com.github.pagehelper.PageHelper;
import com.smart.campus.common.core.page.PageDomain;
import com.smart.campus.common.core.page.TableSupport;
import com.smart.campus.common.utils.DateUtils;
import com.smart.campus.common.utils.StringUtils;
import com.smart.campus.common.utils.sql.SqlUtil;
import com.smart.campus.framework.web.service.DictService;
import com.smart.campus.school.domain.*;
import com.smart.campus.school.mapper.WrongQuestionMapper;
import com.smart.campus.school.service.*;
import com.smart.campus.school.service.impl.StudentServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 定时任务调度(生成学生练习卷)
 * 
 * @author 智慧校园项目组
 */
@Component("createStudentPaperTask")
@Slf4j
public class CreateStudentPaperTask
{
    @Autowired
    private IStudentService studentService;
    @Autowired
    private IStudentPaperService studentPaperService;

    @Autowired
    private IStudentPaperRelationService studentPaperRelationService;
    @Autowired
    private IExamQuestionService examQuestionService;
    @Autowired
    private WrongQuestionMapper wrongQuestionMapper;
    @Autowired
    private DictService dictService;

    public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i)
    {
        System.out.println(StringUtils.format("执行多参方法： 字符串类型{}，布尔类型{}，长整型{}，浮点型{}，整形{}", s, b, l, d, i));
    }

    public void ryParams(String params)
    {
        System.out.println("执行有参方法：" + params);
    }

    public void ryNoParams()
    {

        log.info("开始执行生成错题练习卷");

        int pageSize = 1000;
        Integer pageNum = 1;
        boolean isRun = true;
        while (isRun){
            PageHelper.startPage(pageNum, pageSize, "id");
            List<Student> studentList = studentService.selectStudentList(null);
            pageNum++;
            if(studentList.size() < pageSize){
                isRun = false;
            }

            if(CollectionUtils.isEmpty(studentList)){
                return;
            }
            for (Student student : studentList) {
                log.info("开始执行生成错题练习卷-学生{}",student.getId());
                WrongQuestion wrongQuestion = new WrongQuestion();
                wrongQuestion.setCreateTime(new Date());
                wrongQuestion.setStudentId(student.getId());
                List<WrongQuestion> list = wrongQuestionMapper.selectWrongQuestionListForTask(wrongQuestion);
                log.info("开始执行生成错题练习卷-学生{},错题数{}",student.getId(),list.size());
                if(CollectionUtils.isEmpty(list)){
                    continue;
                }
                Map<Integer,Map<Integer,List<WrongQuestion>>> subjectMap = new TreeMap<>();
                //先按学科分组
                group(subjectMap,list);
                log.info("开始执行生成错题练习卷-学生{},按学科分为{}组",student.getId(),subjectMap.size());
                //分完组按学科进行生成试卷
                List<StudentPaperRelation> relationList = new ArrayList<>();
                for (Map.Entry<Integer, Map<Integer, List<WrongQuestion>>> typeMapEntry : subjectMap.entrySet()) {

                    log.info("开始执行生成错题练习卷-学生{},学科{},分为{}组题型",student.getId(),typeMapEntry.getKey(),typeMapEntry.getValue().size());
                    //每个学科按试题类型对应的数量进行拆分
                    //每个题型最多10道题
                    //每个学科最多生成3套试卷
                    Map<Integer, List<WrongQuestion>> typeMap = typeMapEntry.getValue();
                    //准备生成
                    Map<String,List<WrongQuestion>> resultMap = prepareCreatePaper(typeMap,null,1,1);
                    if(MapUtils.isNotEmpty(resultMap)){
                        startCreate(resultMap,relationList);
                    }
                }
                if(CollectionUtils.isNotEmpty(relationList)){
                    studentPaperRelationService.batchInsertStudentPaperRelation(relationList);
                }

            }


        }

    }

    /**
     * 准备生成
     * @param typeMap
     * @param countMap
     * @param exeCount
     * @return
     */
    private Map<String,List<WrongQuestion>>  prepareCreatePaper(Map<Integer, List<WrongQuestion>> typeMap,Map<String,List<WrongQuestion>> countMap, int exeCount,int paperCount){
       if(countMap == null){
           countMap = new TreeMap<>();
       }
      //  Map<String,List<WrongQuestion>> countMap = new HashMap<>();
        if(exeCount <= 3 && exeCount <= paperCount ){
            for (Map.Entry<Integer, List<WrongQuestion>> typeListEntry : typeMap.entrySet()) {

                Iterator<WrongQuestion> iterator = typeListEntry.getValue().iterator();
                List<WrongQuestion> typeList = new ArrayList<>();
                int curCount = 1;
                //按试题类型加到队列里
                int questionCount = getQuestionCount(typeListEntry.getKey());
                paperCount = (typeListEntry.getValue().size()-1)/questionCount+1;
                log.info("题型【{}】总数{},每套试题上限数{},套数{}",typeListEntry.getKey(),typeListEntry.getValue().size(),questionCount,paperCount);
                while (iterator.hasNext() && curCount <= questionCount){
                    curCount++;
                    WrongQuestion wrongQuestion = iterator.next();
                    //添加到新的试卷组 然后把旧的删除
                    typeList.add(wrongQuestion);
                    iterator.remove();
                }

                //当前体型数量不够，需要从上一套试卷去取数来补
                if(curCount <= questionCount && exeCount > 1){
                    int needAddCount = questionCount - curCount;
                    //上一套试题
                    List<WrongQuestion> preList = countMap.get((exeCount-1)+"_"+typeListEntry.getKey());
                    if(CollectionUtils.isNotEmpty(preList)){
                        int preCount = preList.size();

                        //上一套题数够就截取,不够就全部拿出来用
                        if(preCount > needAddCount){
                            if(paperCount > curCount){
                                List<WrongQuestion> needAddList = preList.subList(preCount-needAddCount,preCount);
                                typeList.addAll(needAddList);
                            }
                        }else {
                            if(preCount > curCount){
                                typeList.addAll(preList);
                            }

                        }
                    }
                }

                countMap.put(exeCount+"_"+typeListEntry.getKey(),typeList);
              //  log.info("开始执行生成错题练习卷-学生{},学科{},题型【{}】,数量{},可生成{}套试卷",student.getId(),typeMapEntry.getKey(),typeListEntry.getKey(),total,count);
            }
            exeCount++;
            prepareCreatePaper(typeMap,countMap,exeCount,paperCount);
        }


        return countMap;
    }

    /**
     * 开始生成
     * @param countMap
     * @param relationList
     */
    private void startCreate(Map<String,List<WrongQuestion>> countMap,List<StudentPaperRelation> relationList){
        Map<Integer,List<WrongQuestion>> quesTypeMap = new HashMap<>();

        for (Map.Entry<String, List<WrongQuestion>> entry : countMap.entrySet()) {
            Integer intKey = Integer.valueOf(entry.getKey().split("_")[0]);
            //同一套试题合并
            if( quesTypeMap.containsKey(intKey)){
                quesTypeMap.get(intKey).addAll(entry.getValue());
            }else {
                quesTypeMap.put(intKey,new ArrayList(entry.getValue()));
            }

        }

        for (Map.Entry<Integer, List<WrongQuestion>> intListEntry : quesTypeMap.entrySet()) {
            //每一套试卷单独处理
            List<WrongQuestion> questionList = intListEntry.getValue();
            //生成试卷
            Long paperId = createPaper(questionList.get(0),intListEntry.getKey());
            for (WrongQuestion question : questionList) {
                StudentPaperRelation relation = new StudentPaperRelation();
                relation.setQuestionId(question.getQuestionId());
                relation.setStudentPaperId(paperId);
                relationList.add(relation);
            }
        }

    }

    /**
     * 分组
     * @param subjectMap
     * @param list
     */
    private void group(Map<Integer,Map<Integer,List<WrongQuestion>>> subjectMap,List<WrongQuestion> list){
        for (WrongQuestion question : list) {
            //先按学科分组
            if(subjectMap.containsKey(question.getExamQuestion().getSubject())){
                //再按题型分组
                Map<Integer,List<WrongQuestion>> typeMap = subjectMap.get(question.getExamQuestion().getSubject());
                if(typeMap.containsKey(question.getExamQuestion().getType())){
                    typeMap.get(question.getExamQuestion().getType()).add(question);
                }else {
                    List<WrongQuestion> typeList = new ArrayList<>();
                    typeList.add(question);
                    typeMap.put(question.getExamQuestion().getType(),typeList);

                }
            }else {
                Map<Integer,List<WrongQuestion>> typeMap = new TreeMap<>();
                List<WrongQuestion> typeList = new ArrayList<>();
                typeList.add(question);
                typeMap.put(question.getExamQuestion().getType(),typeList);
                subjectMap.put(question.getExamQuestion().getSubject(),typeMap);
            }
        }
    }
    /**
     * 生成试卷信息
     * @param question
     */
    private Long createPaper(WrongQuestion question,int index){
        StudentPaper studentPaper = new StudentPaper();
        studentPaper.setStudentId(question.getStudentId());
        studentPaper.setGradeId(question.getExamQuestion().getGradeId());
        studentPaper.setGradeName(question.getExamQuestion().getGradeName());
        studentPaper.setName(DateUtils.getDate()+dictService.getLabel("sc_subject_type",String.valueOf(question.getExamQuestion().getSubject()))
                +"第"+index+"套练习卷");
        studentPaper.setCreateTime(new Date());
        studentPaper.setStatus(1);
        studentPaper.setSubject(question.getExamQuestion().getSubject());
        studentPaperService.insertStudentPaper(studentPaper);
        return studentPaper.getId();
    }

    /**
     * 根据体型获取生成题目数量
     * @param type
     * @return
     */
    private int getQuestionCount(Integer type){

        switch (type){
            case 1 : return 10;
            case 2 : return 5;
            case 3 : return 10;
            case 4 : return 10;
            case 5 : return 10;
            case 6 : return 10;
            case 7 : return 1;
            default: return 5;
        }

    }

    public static void main(String[] args) {
        System.out.println((2-1)/1+1);
    }
}
